package modelado.datos.elementos;

import java.util.Iterator;

public class ObjetoMochilaImpl extends ElementoConVariasInstanciasImpl
		implements ObjetoMochila {

	private Integer valor;
	private Integer peso;

	/**
	 * Constructor
	 * 
	 * @param val
	 *            : valor del objeto
	 * @param pes
	 *            : peso del objeto
	 */
	public ObjetoMochilaImpl(Integer val, Integer pes) {
		// TODO
		this.valor = val;
		this.peso = pes;
	}

	/**
	 * Constructor
	 * 
	 * @param val
	 *            : valor del objeto
	 * @param pes
	 *            : peso del objeto
	 * @param nm
	 *            : numero maximo de instancias del objeto
	 */
	public ObjetoMochilaImpl(Integer val, Integer pes, Integer nm) {
		// TODO
		super(nm);
		this.valor = val;
		this.peso = pes;
		this.setNumInstancias(nm);
	}

	/**
	 * Devuelve el peso
	 */
	public Integer getPeso() {
		// TODO
		return peso;
	}

	/**
	 * Devuelve el valor
	 */
	public Integer getValor() {
		// TODO
		return valor;
	}

	/**
	 * Muestra <codigo,valor,peso, numero de instancias>
	 */
	public String toString() {
		// TODO
		String cad = "<" + this.getCodigo() + "," + this.valor + "," + this.peso + "," + this.getNumInstancias() + ">";
		return cad;
	}

	/**
	 * Dos objetos de la mochila son iguales si: tienen el mismo codigo, numero
	 * maximo de instancia, valor y peso
	 */
	public boolean equals(Object o) {
		boolean r = false;
		// TODO
		if (o instanceof ObjetoMochila)
		{
			ObjetoMochila om = (ObjetoMochila)o;
			r = this.getCodigo() == om.getCodigo() &&
				this.getNumMaxInstancias() == om.getNumMaxInstancias() &&
				this.getValor() == om.getValor() &&
				this.getPeso() == om.getPeso();
		}
		return r;
	}

	/**
	 * HashCode teniendo en cuenta los hashCode propios del codigo, numero de
	 * instancias, valor y peso
	 */
	public int hashCode() {
		// TODO
		return this.getCodigo() + 
				31*this.getNumMaxInstancias() +
				31*31*this.getValor() +
				31*31*31*this.getPeso();
	}

	public Iterator<Elemento> iterator() {
		return new IteradorMochila(this);
	}

	/**
	 * Iterador ropio de ObjetoMochila. La variabilidad ira desde el numero
	 * maximo de instancias del objeto, hasta 1
	 */
	private class IteradorMochila implements Iterator<Elemento> {
		private Integer ninstancias = getNumMaxInstancias();
		private ObjetoMochila om;

		/**
		 * Constructor
		 * 
		 * @param o
		 */
		IteradorMochila(ObjetoMochila o) {
			om = o;
			
		}

		/**
		 * Habra siguiente objetoMochila si el numero de instancias es mayor que
		 * 0
		 */
		public boolean hasNext() {
			// TODO
			return om.getNumInstancias()>0;
		}

		/**
		 * El siguiente elemento establecera el numero de instancias y despues
		 * actualizara dicho numero de instancias decrementandolo en 1.
		 */
		public Elemento next() {
			// TODO
			om.setNumInstancias(ninstancias);
			ninstancias--;
			
			return om;
		}

		public void remove() {
		}

	}
}